class ClassInstance(object):
    """
    类的单列实现
    """
    _instance = None
    _init_end = None

    def __new__(cls, *args, **kwargs):
        """
        :param args:
        :param kwargs:
        """
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self, name, re_init=False):
        """
        实例化属性
        """
        if ClassInstance._init_end and not re_init:
            return
        self.name = name
        ClassInstance._init_end = True

    def __repr__(self):
        """
        返回一个实例的代码表示形式
        :return:
        """
        return "__repr__"

    def __str__(self):
        """
        实例转换为一个字符串
        如果 __str__() 没有被定义，那么就会使用 __repr__() 来代替输出。
        :return:
        """
        return "__str__"

    @classmethod
    def print_class_id(cls):
        print("--------")
        print(id(cls))

    def print_id(self):
        """
        打印自己的id
        :return:
        """
        print(id(self))


class ClassDecorator(object):
    """
    类装饰器实现
    """

    def __init__(self, function):
        self.__function = function

    def __call__(self, *args, **kwargs):
        """
        类调用实现
        :param args:
        :param kwargs:
        :return:
        """
        print("执行开始")
        self.__function(*args, **kwargs)
        print("执行结束")


@ClassDecorator
# decorator_test = ClassDecorator(decorator_test)
def decorator_test(number):
    print("装饰器方法测试执行打印", number)


class ClassFormat:
    """
    类的格式化输出
    d = ClassFormat(2012, 12, 21)
    print(format(d, 'mdy'))

    12/21/2012
    """
    _formats = {
        'ymd': '{d.year}-{d.month}-{d.day}',
        'mdy': '{d.month}/{d.day}/{d.year}',
        'dmy': '{d.day}/{d.month}/{d.year}'
    }

    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

    def __format__(self, code):
        """
        类的格式化 输出
        :param code:
        :return:
        """
        if code == '':
            code = 'ymd'
        fmt = self._formats[code]
        return fmt.format(d=self)


class ClassWith:
    """
    类的with 语句实现

    class_with = ClassWith("oooo")
    with class_with as cw:
        cw.print_id()

    当出现 with语句的时候，对象的 __enter__() 方法被触发，它返回的值 (如果有的话) 会被赋值给as 声明的变量。
    然后，with 语句块里面的代码开始执行。最后，__exit__() 方法被触发进行清理工作。
    """

    def __init__(self, *args, **kwargs):
        self._args = args
        self._kwargs = kwargs
        self.class_with_info = None

    def __enter__(self):
        """
        with 语句开始执行
        :return:
        """
        print("with 语句开始执行")
        self.class_with_info = ClassInstance(0)

        return self.class_with_info

    def __exit__(self, exc_ty, exc_val, tb):
        """
        with 结束 执行
        :param exc_ty:
        :param exc_val:
        :param tb:
        :return:
        """
        print("with 语句结束")
        self.class_with_info.print_id()


from abc import ABCMeta, abstractmethod


class IStream(metaclass=ABCMeta):
    """
    抽象类  不能直接被实例化
    抽象类的目的就是让别的类继承它并实现特定的抽象方法
    """
    @abstractmethod
    def read(self, maxbytes=-1):
        pass

    @abstractmethod
    def write(self, data):
        pass


if __name__ == '__main__':
    pass

